package com.sky.chapter1.deadlock;

/**
 * description: 展示线程死锁状态
 * 死锁形成条件：1.资源互斥 2.构成请求并持有 3.资源不可剥夺 4.环路等待
 * 避免死锁需要破坏掉其中至少一个条件即可。但是目前只有请求并持有条件和环路等待条件可以破坏。
 * 另外使用资源申请的有序性可以破坏死锁。
 * Author by cqb, Date on 2020/7/7，7:08
 *
 *  线程a                                       |    线程b
 *      抢占资源a                               |           抢占资源b
 *                 停下                        |                    停下
 *     ---------------------------------  卡住 ---------------------------------
 *                      想要抢占资源b           |                         想要抢占资源a
 *
 *   导致死锁
 *
 *  线程a                                        |    线程b
 *      抢占资源a成功                            |           抢占资源a失败   停下
 *                      想要抢占资源b            |                           停下
 *                            抢占资源b         |                            停下
 *                                释放资源a    |                               抢占资源a
 *                                释放资源b    |                                  抢占资源b
 *   不会导致死锁
 */
public class DeadLockTest2 {
    private static Object resourceA =new Object();
    private static Object resourceB =new Object();

    public static void main(String[] args) {
        //1.用资源申请的有序性改变请求并持有条件打破死锁状态

        Thread threadA=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (resourceA){
                    System.out.println(Thread.currentThread()+"get ResourceA");
                    try {
                        Thread.sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread()+"waiting get ResourceB");
                    synchronized (resourceB){
                        System.out.println(Thread.currentThread()+"get ResourceB");
                    }
                }
                }
        }, "线程A");




        Thread threadB=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (resourceA){
                    //演示死锁状态
//                synchronized (resourceB){
                    System.out.println(Thread.currentThread()+"get ResourceB");
                    try {
                        Thread.sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread()+"waiting get ResourceA");
                    synchronized (resourceB){
                        //演示死锁状态
//                    synchronized (resourceA){
                        System.out.println(Thread.currentThread()+"get ResourceA");
                    }
                }
            }
        }, "线程B");

        //启动线程A
        threadA.start();
        //启动线程B
        threadB.start();

    }



}
